package com.relytosoft.mizar.media.system.services.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.StrUtil;
import com.relytosoft.dubhe.common.core.object.ResponseResult;
import com.relytosoft.dubhe.common.core.utils.BeanCopyUtils;
import com.relytosoft.dubhe.common.log.annotation.OpLog;
import com.relytosoft.dubhe.common.log.enums.OpTypeEnum;
import com.relytosoft.mizar.media.system.api.entity.SysDistrict;
import com.relytosoft.mizar.media.system.api.pojo.dto.SysDistrictDto;
import com.relytosoft.mizar.media.system.api.pojo.vo.SysDistrictVo;
import com.relytosoft.mizar.media.system.services.service.DistrictSyncService;
import com.relytosoft.mizar.media.system.services.service.SysDistrictService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;

/**
 * 区域
 *
 * @Author SunLi
 * @Date: 2022/4/7 14:56
 * @Version 1.0
 */
@Validated
@RestController
@RequestMapping("/system/district")
@Api(tags = "区域相关接口")
public class SysDistrictController {
    @Resource
    private SysDistrictService sysDistrictService;

    @Resource
    private DistrictSyncService districtSyncService;

    @GetMapping("/list/exclude/{id}")
    @ApiOperation("获得有效区域列表信息（排除节点）")
    public ResponseResult<List<SysDistrict>> selectSysDistrictListEx(@ApiParam("区域ID") @PathVariable(value = "id", required = false) int id) {
        List<SysDistrict> districts = sysDistrictService.selectSysDistrictList("");
        districts.removeIf(d -> d.getId().equals(id));
        return ResponseResult.ok(districts);
    }

    @GetMapping(value = "/list")
    @SaCheckPermission("system:district:list")
    @ApiOperation("获得所有区域列表信息")
    public ResponseResult<List<SysDistrictVo>> selectSysDistrictVoList(SysDistrictDto sysDistrict) {
        SysDistrict entity= BeanCopyUtils.copy(sysDistrict,SysDistrict.class);
        return ResponseResult.ok(sysDistrictService.selectSysDistrictVoList(entity));
    }

    @GetMapping(value = "/listAll")
    @ApiOperation("获得所有有效区域列表信息(包含根节点)")
    public ResponseResult<List<SysDistrict>> selectDeptListAll() {
        List<SysDistrict> list = sysDistrictService.selectSysDistrictList("");
        SysDistrict district = new SysDistrict();
        district.setId(0);
        district.setParentId(0);
        district.setName("区域");
        district.setSort(0);
        district.setStatus(1);
        list.add(0, district);
        return ResponseResult.ok(list);
    }

    @GetMapping(value = "/treelist")
    @ApiOperation("获得有效区域树列表信息")
    public ResponseResult<List<Tree<Integer>>> selectDistrictTreeList(@ApiParam("区域名称")@RequestParam(required = false) String name) {
        return ResponseResult.ok(sysDistrictService.buildSysDistrictTreeSelect(sysDistrictService.selectSysDistrictList(name)));
    }

    @PostMapping(value = "/insert")
    @SaCheckPermission("system:district:insert")
    @ApiOperation("添加区域信息")
    @OpLog(msg = "添加区域信息", opType = OpTypeEnum.INSERT)
    public ResponseResult<Void> insertSysDistrict(@Valid @RequestBody SysDistrictDto sysDistrict) {
        SysDistrict entity= BeanCopyUtils.copy(sysDistrict,SysDistrict.class);
        handleDepth(entity);
        entity.setId(null);
        entity.setStatus(1);
        if(entity.getSort()==null){
            entity.setSort(0);
        }
        String mes = validate(entity);
        if (!StrUtil.isEmpty(mes)) {
            return ResponseResult.fail(mes);
        }
        boolean result = sysDistrictService.save(entity);
        if (result) {
            Integer relatedPlatformId = districtSyncService.insertDistrictSync(entity);
            if (relatedPlatformId > 0) {
                districtSyncService.districtSync(entity, relatedPlatformId);
            }
            return ResponseResult.ok();
        }
        return ResponseResult.fail();
    }

    @PutMapping(value = "/update")
    @SaCheckPermission("system:district:update")
    @ApiOperation("修改区域信息")
    @OpLog(msg = "修改区域信息", opType = OpTypeEnum.UPDATE)
    public ResponseResult<Void> updateSysDistrict(@Valid @RequestBody SysDistrictDto sysDistrict) {
        SysDistrict entity= BeanCopyUtils.copy(sysDistrict,SysDistrict.class);
        handleDepth(entity);
        String mes = validate(entity);
        if (!StrUtil.isEmpty(mes)) {
            return ResponseResult.fail(mes);
        }
        boolean result = sysDistrictService.updateById(entity);

        if (result) {
            return ResponseResult.ok();
        }
        return ResponseResult.fail();
    }

    @PutMapping(value = "/updatestatus/{id}/{status}")
    @SaCheckPermission("system:district:updatestatus")
    @ApiOperation("修改区域信息状态")
    @OpLog(msg = "修改区域信息状态", opType = OpTypeEnum.SET)
    public ResponseResult<Void> setSysDistrictStatus(@PathVariable int id, @PathVariable int status) {
        if (status == 0) {
            if (!sysDistrictService.canDisable(id)) {
                return ResponseResult.fail("区域存在有效的子区域！");
            }
            //todo 禁用区域时如果区域已有设备，不允许禁用
        }
        int result = sysDistrictService.updateSysDistrictStatus(id, status);
        if (result > 0) {
            return ResponseResult.ok();
        }
        return ResponseResult.fail();
    }

    @GetMapping(value = "/{id}")
    @SaCheckPermission("system:district:getinfo")
    @ApiOperation("获得区域信息")
    public ResponseResult<SysDistrictVo> getSysDistrict(@PathVariable int id) {
        return ResponseResult.ok(sysDistrictService.getSysDistrictVo(id));
    }

    /*
    采用消息队列处理同步后，暂不需要手动同步功能
    @PutMapping(value = "/sync/{id}")
    @ApiOperation("区域信息同步")
    @OpLog(msg = "区域信息同步", opType = OpTypeEnum.OTHER)
    public ResponseResult<Void> districtSync(@PathVariable int id) {
        if (id == 0) {
            return ResponseResult.fail("参数错误！");
        }
        try {
            SysDistrict entity = sysDistrictService.getById(id);
            districtSyncService.districtSync(entity, 0);
            return ResponseResult.ok();
        } catch (Exception ex) {
            return ResponseResult.fail();
        }
    }

    @PutMapping(value = "/syncall")
    @ApiOperation("区域信息同步所有")
    @OpLog(msg = "区域信息同步所有", opType = OpTypeEnum.OTHER)
    public ResponseResult<Void> districtSyncAll() {
        districtSyncService.checkRootDistrictSync();
        List<DistrictSyncVo> sysDistrictList = sysDistrictService.getDistrictSyncList(mizarMediaProperties.getStoreType());
        if (sysDistrictList == null || sysDistrictList.size() == 0) {
            return ResponseResult.ok("区域已全部同步");
        }
        //消息队列用此逻辑处理
        //当前需要同步的第一级深度
        int minDepth = sysDistrictList.get(0).getDepth();
        List<DistrictSyncVo> districtSyncList = sysDistrictList.stream().filter(item -> item.getDepth() == minDepth).collect(Collectors.toList());
        //第三方添加区域
        districtSyncService.districtListSync(districtSyncList);

        /*采用消息队列后，不能用此逻辑进行同步，会一直重复发送消息,只能每次点同步处理需同步的第一级深度
        //当前需要同步的第一级深度
        int minDepth = sysDistrictList.get(0).getDepth();
        //第一级深度待同步区域
        List<DistrictSyncVo> districtSyncList = sysDistrictList.stream().filter(item -> item.getDepth() == minDepth).collect(Collectors.toList());
        while (districtSyncList != null && districtSyncList.size() > 0) {
            //第三方添加区域
            districtSyncService.districtListSync(districtSyncList);

            //重新查询待同步区域
            sysDistrictList = sysDistrictService.getDistrictSyncList(mizarMediaProperties.getStoreType());
            int newMinDepth = sysDistrictList.get(0).getDepth();
            //第一级深度待同步区域
            districtSyncList = sysDistrictList.stream().filter(item -> item.getDepth() == newMinDepth).collect(Collectors.toList());
        }*//*
        return ResponseResult.ok();

    }*/
    //todo 导入

    //todo 导出
    /**
     * 处理区域信息深度信息
     *
     * @param entity 区域实体
     */
    private void handleDepth(SysDistrict entity) {
        if (entity.getParentId() != 0) {
            SysDistrict parentDistrict = sysDistrictService.getById(entity.getParentId());
            entity.setDepth(parentDistrict.getDepth() + 1);
            entity.setDepthPath(parentDistrict.getDepthPath() + ',' + entity.getParentId());
        } else {
            entity.setDepth(1);
            entity.setDepthPath("0");
        }
    }

    private String validate(SysDistrict entity) {
        if (StrUtil.isEmpty(entity.getDepthPath())) {
            return "深度路径不能为空！";
        }
        if (entity.getDepth() == 0) {
            return "深度不能为0！";
        }
        if (StrUtil.isEmpty(entity.getName())) {
            return "区域名称不能为空！";
        }
        if (StrUtil.isEmpty(entity.getCode())) {
            return "区域编码不能为空！";
        }
        if (entity.getSecurityLevelId() ==null) {
            return "安全级别不能为空！";
        }
        if(entity.getSort()==null){
            return "排序不能为空！";
        }
        //验证区域编号不能重复
        if (!sysDistrictService.checkCodeUnique(entity)) {
            return "区域编码已存在！";
        }
        //验证同一深度的区域名称是否重复
        if (!sysDistrictService.checkNameUnique(entity)) {
            return "区域名称在同级区域中已存在！";
        }
        return "";
    }
}
